package boot.spring.service.impl;

import boot.spring.config.CommonImportListener;
import boot.spring.config.ServiceException;
import boot.spring.service.TouristService;
import boot.spring.util.*;
import boot.spring.vo.TouristImportVo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

@Service
@Slf4j
public class TouristServiceImpl implements TouristService {

    @Value("${tour.token}")
    private String token;

    @Value("${tour.client1}")
    private String client1;

    @Value("${tour.client2}")
    private String client2;

    @Value("${tour.file}")
    private String file;

    @Resource
    RedissonClient redissonClient;

    @Override
    public List<TouristImportVo> importTourist(String fileName) {
        List<String> failReasonList = new ArrayList<>();
        try {
            InputStream inputStream = new FileInputStream(fileName);
            // 解析 Excel
            List<TouristImportVo> touristList = EasyExcelUtil.readExcel(inputStream, TouristImportVo.class,
                    new CommonImportListener<>());
            // 判断是否解析到有效数据
            if (CollUtil.isEmpty(touristList)) {
                throw new ServiceException("导入失败,Excel 文档数据为空");
            }
            // 基本参数校验
            touristList.forEach(tourist -> failReasonList.addAll(ValidateUtil.validExcel(tourist)));
            if (CollUtil.isNotEmpty(failReasonList)) {
                throw new ServiceException(failReasonList.stream().collect(Collectors.joining(",")));
            }
//            // TODO 业务参数校验
//            touristList.forEach(student -> {
//                log.info("业务参数校验学生信息: {}", student);
//
//            });

//            // 校验通过的对象数
//            response.setSuccessCount(studentList.size());

            // TODO 保存到数据库
            return touristList;
        } catch (Exception e) {
            log.error("Excel 解析失败",e);
            throw new ServiceException(e.getMessage());
        }
    }

    @Override
    public Map<String,Long> submitOrderOne(List<Map<String, Object>> allOrder, String dayStr) {
        boolean isSuccess = false;
        Map<String,Long> idMap = new HashMap<>();
        while (!isSuccess){
            if(CollUtil.isEmpty(allOrder)){return idMap;}
            String url = "https://lotsmg.dpm.org.cn/tyApi/zybprod/market/orderTicket";
            Map<String, String> head = new HashMap<>();
            head.put("Tyauthtoken",token);
            JSONObject paramsMap = new JSONObject();
            paramsMap.put("scenicId", "242");
            paramsMap.put("useDate", dayStr);
            paramsMap.put("ticketListVOS", allOrder);
            System.out.println(paramsMap.toJSONString());
            String result = HttpClientUtils.postJson(url,null,head,paramsMap.toJSONString());
            JSONObject object = JSON.parseObject(result);
            Integer code = object.getInteger("status");
            if(!code.equals(200)){
//                if(result.contains("游玩日没有设置价格")){
//                    throw new ServiceException("游玩日没有设置价格");
//                }
                continue;
            }
            isSuccess = true;
            JSONObject data = object.getJSONObject("data");
            JSONArray array = data.getJSONArray("ticketListVOS");
            if (CollUtil.isEmpty(array)){
                return idMap;
            }
            for (int i = 0; i < array.size(); i++) {
                JSONObject id = array.getJSONObject(i);
                Long ticketId = id.getLong("id");
                String ticketName = id.getString("ticketName");
                idMap.put(ticketName,ticketId);
            }
        }
        return idMap;
    }

    @Override
    public void initRedis() {
        List<TouristImportVo> touristImportVoList =  this.importTourist(file);
        // 获取抢票优先级
        String priority = StringUtil.isEmpty(touristImportVoList.get(0).getQpyxj())? "上午" : touristImportVoList.get(0).getQpyxj();
        String guideName = touristImportVoList.get(0).getGuideName();
        RBucket<String> stringdata = redissonClient.getBucket("PRIORITY_KEY");
        RBucket<String> guide = redissonClient.getBucket("GUIDE_KEY");
        stringdata.set(priority);
        guide.set(guideName);
        RMap<String, Object> map = redissonClient.getMap("TOUR_KEY");
        List<TouristImportVo> lnList = new ArrayList<>();
        List<TouristImportVo> xsList = new ArrayList<>();
        List<TouristImportVo> crList = new ArrayList<>();
        List<TouristImportVo> wcnList = new ArrayList<>();
        for (TouristImportVo touristImportVo : touristImportVoList) {
            switch (touristImportVo.getTypeName()){
                case "老年人票":
                    lnList.add(touristImportVo);
                    break;
                case "学生票":
                    xsList.add(touristImportVo);
                    break;
                case "成人团队票":
                    crList.add(touristImportVo);
                    break;
                case "团队未成年人免费票":
                    wcnList.add(touristImportVo);
                    break;
            }
        }
        if(CollUtil.isNotEmpty(lnList)){
            map.put("ln",lnList);
        }
        if(CollUtil.isNotEmpty(xsList)){
            map.put("xs",xsList);
        }
        if(CollUtil.isNotEmpty(crList)){
            map.put("cr",crList);
        }
        if(CollUtil.isNotEmpty(wcnList)){
            map.put("wcn",wcnList);
        }
    }


    @Override
    public Boolean submitOrderTwo(Map<String,List<TouristImportVo>> dataMap, String priority, String guideName, Map<String, Long> ticketIdMap, String dayStr) throws ParseException, InterruptedException {

        boolean isSucess = false;

        while (!isSucess){
            try{
                // 设置请求Header
                Map<String, String> head = new HashMap<>();
                head.put("Tyauthtoken",token);
                // 设置请求参数
                JSONObject param = new JSONObject();

                param.put("scenicId",242);
                param.put("scenicName","故宫博物院");
                long currentTimeMillis = System.currentTimeMillis();
                param.put("timesTamp", currentTimeMillis);
                param.put("saveOrderFlag","F");
                // 获取导游信息
                Map<String,Object> guideMap = this.getGuideInfo();
                JSONObject guiJson = (JSONObject) guideMap.get(guideName);
                JSONObject contactPerson = new JSONObject();
                contactPerson.put("authType","IC");
                contactPerson.put("linkName",guiJson.getString("name"));
                contactPerson.put("linkTel",guiJson.getString("mobile"));
                contactPerson.put("certNo",guiJson.getString("idNumber"));
                param.put("contactPerson",contactPerson);
//                Thread.sleep(10 * 1000);

                Double totalPrice = 0D;
                JSONArray goodsList = new JSONArray();
                if (dataMap.containsKey("老年人票")){
                    // 游客
                    JSONObject good = new JSONObject();
                    JSONArray customerInfos = new JSONArray();
                    List<TouristImportVo> ln = dataMap.get("老年人票");
                    for (TouristImportVo touristImportVo : ln) {
                        JSONObject customerInfo = new JSONObject();
                        customerInfo.put("authType","IC");
                        customerInfo.put("certNo",touristImportVo.getCard());
                        customerInfo.put("realName",touristImportVo.getName());
                        customerInfo.put("touristType",null);
                        customerInfos.add(customerInfo);
                    }
                    good.put("customerInfos",customerInfos);
                    good.put("goodsCode","TYMP20220704005223");
                    good.put("isGiftTicket","F");
                    good.put("occDate", dayStr);
                    if (priority.equals("上午")){
                        good.put("occStartTime","06:00");
                        good.put("occEndTime","12:00");
                    }else{
                        good.put("occStartTime","11:00");
                        good.put("occEndTime","17:00");
                    }
                    good.put("quantity",ln.size());
                    if (ticketIdMap.containsKey("老人票")){
                        good.put("ticketId",ticketIdMap.get("老人票"));
                    }
                    goodsList.add(good);
                    totalPrice += ln.size() * 30 *100;
                }
                if (dataMap.containsKey("学生票")){
                    // 游客
                    JSONObject good = new JSONObject();
                    JSONArray customerInfos = new JSONArray();
                    List<TouristImportVo> xs = dataMap.get("学生票");
                    for (TouristImportVo touristImportVo : xs) {
                        JSONObject customerInfo = new JSONObject();
                        customerInfo.put("authType","IC");
                        customerInfo.put("certNo",touristImportVo.getCard());
                        customerInfo.put("realName",touristImportVo.getName());
                        customerInfo.put("touristType",null);
                        customerInfos.add(customerInfo);
                    }
                    good.put("customerInfos",customerInfos);
                    good.put("goodsCode","TYMP20220704005225");
                    good.put("isGiftTicket","F");
                    good.put("occDate", dayStr);
                    if (priority.equals("上午")){
                        good.put("occStartTime","06:00");
                        good.put("occEndTime","12:00");
                    }else{
                        good.put("occStartTime","11:00");
                        good.put("occEndTime","17:00");
                    }
                    good.put("quantity",xs.size());
                    if (ticketIdMap.containsKey("学生票")){
                        good.put("ticketId",ticketIdMap.get("学生票"));
                    }
                    goodsList.add(good);
                    totalPrice += xs.size() * 20 *100;
                }
                if (dataMap.containsKey("成人团队票")){
                    // 游客
                    JSONObject good = new JSONObject();
                    JSONArray customerInfos = new JSONArray();
                    List<TouristImportVo> cr = dataMap.get("成人团队票");
                    for (TouristImportVo touristImportVo : cr) {
                        JSONObject customerInfo = new JSONObject();
                        customerInfo.put("authType","IC");
                        customerInfo.put("certNo",touristImportVo.getCard());
                        customerInfo.put("realName",touristImportVo.getName());
                        customerInfo.put("touristType",null);
                        customerInfos.add(customerInfo);
                    }
                    good.put("customerInfos",customerInfos);
                    good.put("goodsCode","TYMP20220704005220");
                    good.put("isGiftTicket","F");
                    good.put("occDate", dayStr);
                    if (priority.equals("上午")){
                        good.put("occStartTime","06:00");
                        good.put("occEndTime","12:00");
                    }else{
                        good.put("occStartTime","11:00");
                        good.put("occEndTime","17:00");
                    }
                    good.put("quantity",cr.size());
                    if (ticketIdMap.containsKey("成人团队票")){
                        good.put("ticketId",ticketIdMap.get("成人团队票"));
                    }
                    goodsList.add(good);
                    totalPrice += cr.size() * 60 *100;
                }
                if (dataMap.containsKey("团队未成年人免费票")){
                    // 游客
                    JSONObject good = new JSONObject();
                    JSONArray customerInfos = new JSONArray();
                    List<TouristImportVo> wcn = dataMap.get("团队未成年人免费票");
                    for (TouristImportVo touristImportVo : wcn) {
                        JSONObject customerInfo = new JSONObject();
                        customerInfo.put("authType","IC");
                        customerInfo.put("certNo",touristImportVo.getCard());
                        customerInfo.put("realName",touristImportVo.getName());
                        customerInfo.put("touristType",null);
                        customerInfos.add(customerInfo);
                    }
                    good.put("customerInfos",customerInfos);
                    good.put("goodsCode","TYMP20220709005358");
                    good.put("isGiftTicket","F");
                    good.put("occDate", dayStr);
                    if (priority.equals("上午")){
                        good.put("occStartTime","06:00");
                        good.put("occEndTime","12:00");
                    }else{
                        good.put("occStartTime","11:00");
                        good.put("occEndTime","17:00");
                    }
                    good.put("quantity",wcn.size());
                    if (ticketIdMap.containsKey("团队未成年人免费票")){
                        good.put("ticketId",ticketIdMap.get("团队未成年人免费票"));
                    }
                    goodsList.add(good);
                }
                // 获取总价
                param.put("totalPrice",totalPrice.longValue() + "");
                param.put("goodsList",goodsList);
                // 获取sign
                String sign = encryptOrder(goodsList,currentTimeMillis);
                param.put("sign",sign);
                String url = "https://lotsmg.dpm.org.cn/tyApi/zyborder/order/saveUnpaidOrder";
                String result = HttpClientUtils.postJson(url, null,head,param.toJSONString());
                JSONObject object = JSON.parseObject(result);
                Integer code = object.getInteger("status");
                if(code.equals(200)){
                    isSucess = true;
                }else{
                    isSucess = false;
                }
            } catch (Exception e) {
                continue;
            }
        }

        return isSucess;
    }

    private Map<String,Object> getGuideInfo() {
        RestTemplate restTemplate = new RestTemplate();
        // 设置请求Header
        HttpHeaders headers = new HttpHeaders();
        headers.set("Tyauthtoken", token);
        // 设置请求参数
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("corpCode", "BJQN");
        map.add("currentPage", "1");
        map.add("itemsPerPage", "50");
        String url = "https://lotsmg.dpm.org.cn/tyApi/zybuser/touristguide/queryTouristGuide";
        // 创建请求实体
        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(map, headers);
        // 发送POST请求并获取响应结果
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        String result = responseEntity.getBody();
        JSONObject res = JSON.parseObject(result);
        Integer code = res.getInteger("status");
        if(!code.equals(200)){
            throw new ServiceException(res.getString("statusDesc"));
        }
        JSONObject data = res.getJSONObject("data");
        JSONArray resultList = data.getJSONArray("resultList");
        Map<String,Object> guideMap = new HashMap<>();
        for (int i = 0; i < resultList.size(); i++) {
            JSONObject ress = resultList.getJSONObject(i);
            guideMap.put(ress.getString("name"), ress);
        }
        return guideMap;
    }

//    /**
//     * 库存解密
//     * @param encryptNum
//     * @return
//     */
//    private Integer encryptStock(String encryptNum) {
//        String url = "http://127.0.0.1:5612/business-demo/invoke?group=test_web&action=lotsmg&a="+encryptNum+"&bind_client="+client1;
//        String result = HttpUtil.get(url);
//        JSONObject json = JSON.parseObject(result);
//        return Integer.parseInt(json.getString("data").split("_")[0]);
//    }

    private String encryptOrder(JSONArray str, long time) throws IOException {
        String params = "group=test_web&action=getEncryptSign&l="+str+"&m="+time+"&bind_client=" + client2;
        URL url = new URL("http://127.0.0.1:5612/business-demo/invoke");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("POST");
        httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write(params);
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();
        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
        JSONObject json = JSON.parseObject(response);
        return json.getString("data");
    }


    public static void main(String[] args) throws IOException {
        URL url = new URL("http://dengta666:Aa123456@lotsmg.dpm.org.cn/tyApi/zyborder/order/saveUnpaidOrder");
//        URL url = new URL("https://lotsmg.dpm.org.cn/tyApi/zyborder/order/saveUnpaidOrder");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("POST");

        httpConn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");

        httpConn.setRequestProperty("tyAuthToken", "F6AB2F98A0714342929CFCACF3BD86B0");

        httpConn.setDoOutput(true);
        long currentTimeMillis = System.currentTimeMillis();
        String data = "[{\"goodsCode\":\"TYMP20220704005220\",\"ticketId\":1035,\"quantity\":1,\"occDate\":\"2024-09-14\",\"isGiftTicket\":\"F\",\"occStartTime\":\"06:00\",\"occEndTime\":\"12:00\",\"customerInfos\":[{\"authType\":\"IC\",\"certNo\":\"140122199405301115\",\"realName\":\"董鑫\"}]}]";
//        String sign = encryptOrder(data, currentTimeMillis);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        String json = "{\"totalPrice\":\"12000\",\"goodsList\":[{\"goodsCode\":\"TYMP20220704005220\",\"ticketId\":1035,\"quantity\":2,\"occDate\":\"2024-09-14\",\"isGiftTicket\":\"F\",\"occStartTime\":\"06:00\",\"occEndTime\":\"12:00\",\"customerInfos\":[{\"authType\":\"IC\",\"certNo\":\"140122199405301115\",\"realName\":\"董鑫\"},{\"authType\":\"IC\",\"certNo\":\"140122199402111121\",\"realName\":\"赵素萍\"}]}],\"contactPerson\":{\"linkName\":\"蔡骏峰\",\"linkTel\":\"13911720701\",\"certNo\":\"110223198708216024\",\"authType\":\"IC\"},\"saveOrderFlag\":\"F\",\"scenicId\":242,\"scenicName\":\"故宫博物院\",\"timesTamp\":1725781879504,\"sign\":\"fe995ab94f1810e5f39a46158d1a8c6c6b1466c743c494d0d3445d8e2ee28c4925330f90411dc153fd573b411b0af234\"}";
        JSONObject json1 = JSON.parseObject(json);


        System.out.println(currentTimeMillis);
//        json1.put("timesTamp",currentTimeMillis);
//        json1.put("sign",sign);
        System.out.println(json1.toJSONString());
        writer.write(json1.toJSONString());
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}
